【MySQL】PRIMARY KEY制約 - 主キー・プライマリーキー(データを識別するカラム)

【MySQL】PRIMARY KEY制約 - 主キー・プライマリーキー(データを識別するカラム)

MySQLのPRIMARY KEY制約について解説します。

検証環境

主キー(プライマリーキー)

主キーはプライマリーキーとも呼び、“レコードを一意に識別するカラムの集合”です。

任意のカラムに設定でき、複数カラムの場合は複合キーと呼びます。

主キーのフィールドは重複せず、固有の値を格納するため、一般的にはIDや連番のように重複しない特性を持つカラムを主キーとします。

PRIMARY KEY制約

PRIMARY KEY制約は“主キー(プライマリーキー)を設定する制約”です。

主キーに設定したカラムはNULLが許可されず、必ず値を格納する必要があります。

また、インデックスが自動で作成されます。

主キー

1つのカラムのみを主キーとする場合、カラム定義に合わせて設定できます。

基本構文

カラム定義 PRIMARY KEY

カラム定義に続いて、PRIMARY KEYを記述します。

サンプル

mysql> /* テーブル作成 */
mysql> CREATE TABLE items (
    ->     id INT PRIMARY KEY,
    ->     name VARCHAR(20),
    ->     price INT,
    ->     stock INT
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> /* テーブル情報 */
mysql> DESC items;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   | PRI | NULL    |       |
| name  | varchar(20) | YES  |     | NULL    |       |
| price | int         | YES  |     | NULL    |       |
| stock | int         | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql> /* インデックス確認 */
mysql> SHOW INDEX FROM items;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| items |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.00 sec)

mysql> /* データ追加 */
mysql> INSERT INTO items VALUE ( 1, 'Apple', 200, 10 );
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO items VALUE ( 1, 'Orange', 150, 3 );
ERROR 1062 (23000): Duplicate entry '1' for key 'items.PRIMARY'

mysql> INSERT INTO items VALUE ( 2, 'Pineapple', 1100, 3 );
Query OK, 1 row affected (0.00 sec)

主キーのカラムはDESCで表示したテーブル情報のKey項目にPRIが表示され、Null項目はNOになります。

また、値の重複ができないため、2回目のレコード追加はエラーになりました。

複合キー

複数カラムからなる複合キーとする場合、カラム定義とは別に定義を追加します。

基本構文

CREATE TABLE テーブル名 (
    カラム定義1,
    カラム定義2,
    カラム定義3,
    PRIMARY KEY( カラム1, カラム2 )
);

テーブル定義にPRIMARY KEY(カラム1, カラム2)を追加します。

サンプル

mysql> /* テーブル作成 */
mysql> CREATE TABLE items (
    ->     id INT,
    ->     name VARCHAR(20),
    ->     price INT,
    ->     stock INT,
    ->     PRIMARY KEY ( id, name )
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> /* テーブル情報 */
mysql> DESC items;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   | PRI | NULL    |       |
| name  | varchar(20) | NO   | PRI | NULL    |       |
| price | int         | YES  |     | NULL    |       |
| stock | int         | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

mysql> /* インデックス確認 */
mysql> SHOW INDEX FROM items;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| items |          0 | PRIMARY  |            1 | id          | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| items |          0 | PRIMARY  |            2 | name        | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.00 sec)

mysql> /* データ追加 */
mysql> INSERT INTO items VALUE ( 1, 'Apple', 200, 10 );
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO items VALUE ( 1, 'Orange', 150, 3 );
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO items VALUE ( 2, 'Apple', 250, 10 );
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO items VALUE ( 1, 'Apple', 200, 10 );
ERROR 1062 (23000): Duplicate entry '1-Apple' for key 'items.PRIMARY'

idnameのカラムを主キーに設定しています。

複合キーはデータの組み合わせ単位での重複はできませんが、一方のみの重複は許可されるので、2、3回目のレコード追加は正常に処理されます。

4回目の追加はidnameの組み合わせが重複するためエラーが発生しました。